<template>
  <view class="container">
    <view class="background-container" v-if="generatedImage">
      <image class="background-image" :src="generatedImage" mode="aspectFill"></image>
      <view class="background-overlay"></view>
    </view>
    
    <view class="content">
      <text class="title">AI图像生成器</text>
      
      <view class="form-item">
        <text class="label">提示词：</text>
        <input class="input" v-model="prompt" placeholder="输入图像描述..." />
      </view>
      
      <view class="form-item">
        <text class="label">模型：</text>
        <picker class="picker" @change="onModelChange" :value="modelIndex" :range="availableModels">
          <view class="picker-text">{{ availableModels[modelIndex] || '选择模型' }}</view>
        </picker>
      </view>
      
      <view class="form-item">
        <text class="label">尺寸：</text>
        <picker class="picker" @change="onSizeChange" :value="sizeIndex" :range="imageSizes" range-key="name">
          <view class="picker-text">{{ imageSizes[sizeIndex].name }}</view>
        </picker>
      </view>
      
      <view class="form-item">
        <text class="label">生成数量：</text>
        <slider :value="imageCount" :min="1" :max="6" :step="1" :block-size="18" show-value @change="onCountChange" />
      </view>
      
      <!-- 翻译结果显示区域 -->
      <view class="translate-container" v-if="showTranslation || isAILoading">
        <view class="translate-content">
          <text class="original-text">原文: {{originalPrompt}}</text>
          <view class="translated-text-container">
            <text class="translated-text">处理后: {{processedPrompt}}</text>
            <view v-if="isAILoading" class="typing-indicator">
              <view class="dot"></view>
              <view class="dot"></view>
              <view class="dot"></view>
            </view>
          </view>
        </view>
        <view class="translate-actions" v-if="!isAILoading">
          <view class="translate-action" @click="useProcessedPrompt">使用处理后提示词</view>
          <view class="translate-action" @click="cancelProcessing">取消</view>
        </view>
      </view>
      
      <view class="button-group">
        <button @click="processPrompt" class="process-btn" :disabled="isAILoading || isGenerating">处理提示词</button>
        <button @click="generateImages" class="generate-btn" :disabled="isGenerating">
          {{ isGenerating ? '生成中...' : '生成图像' }}
        </button>
        <button @click="clearImages" class="clear-btn" v-if="generatedImages.length > 0">清除图像</button>
      </view>
      
      <view class="loading-container" v-if="isGenerating">
        <view class="loading-spinner"></view>
        <text class="loading-text">AI 正在绘制图像 ({{generatedCount}}/{{imageCount}})，请稍候...</text>
      </view>
      
      <view class="image-grid" v-if="generatedImages.length > 0">
        <view v-for="(image, index) in generatedImages" :key="index" class="image-item">
          <image :src="image.url" mode="aspectFill" class="generated-image" @click="previewImage(index)"></image>
          <view class="image-overlay">
            <text class="image-seed">Seed: {{ image.seed }}</text>
          </view>
        </view>
      </view>
    </view>
    
    <!-- 隐藏的AI聊天组件 -->
    <ai-chat ref="aiChat" @ai-message="handleAIMessage"
      @messages-updated="handleMessagesUpdated" @loading="handleAILoading" @error="handleAIError"></ai-chat>
  </view>
</template>

<script>
import { getPic2 } from '@/utils/img.js'
import { generateImageUrl } from '@/utils/im2.js'
import request from '@/utils/request.js'
import aiChat from '@/components/ai-chat/ai-chat.vue'

export default {
  components: {
    aiChat
  },
  data() {
    return {
      prompt: '',
      originalPrompt: '',
      generatedImage: '',
      imageGenerating: false,
      modelIndex: 0,
      sizeIndex: 0,
      quantityIndex: 0,
      styleIndex: 0,
      negativePrompt: '',
      availableModels: ['Stable Diffusion', 'Midjourney', 'DALL-E'],
      imageSizes: [
        { name: '512 x 512', width: 512, height: 512 },
        { name: '768 x 768', width: 768, height: 768 },
        { name: '1024 x 1024', width: 1024, height: 1024 },
        { name: '512 x 768', width: 512, height: 768 },
        { name: '768 x 512', width: 768, height: 512 },
        { name: '1024 x 768', width: 1024, height: 768 },
        { name: '768 x 1024', width: 768, height: 1024 }
      ],
      quantities: ['1张', '2张', '4张', '6张', '9张'],
      styles: ['自然写实', '动漫风格', '油画风格', '水彩画', '素描', '像素艺术', '未来主义', '赛博朋克'],
      translationTimeout: null,
      maxTranslationTime: 30000, // 30秒超时
      isAILoading: false,
      aiPrompt: '', // AI改进后的提示词
      showAdvanced: false, // 是否显示高级选项
      generatedImages: [],
      generatedCount: 0,
      imageCount: 4,
      showTranslation: false,
      processedPrompt: ''
    }
  },
  
  methods: {
    onModelChange(e) {
      this.modelIndex = e.detail.value;
    },
    
    onSizeChange(e) {
      this.sizeIndex = e.detail.value;
    },
    
    onCountChange(e) {
      this.imageCount = e.detail.value;
    },
    
    // 处理提示词
    processPrompt() {
      // 如果没有输入提示词，直接返回
      if (!this.prompt.trim()) {
        uni.showToast({
          title: '请输入提示词',
          icon: 'none'
        });
        return;
      }
      
      // 记录原始提示词
      this.originalPrompt = this.prompt;
      
      // 设置加载状态
      this.isAILoading = true;
      
      // 显示加载提示
      uni.showLoading({
        title: '正在优化提示词...',
        mask: true
      });
      
      // 设置提示词处理超时处理
      if (this.translationTimeout) {
        clearTimeout(this.translationTimeout);
      }
      
      this.translationTimeout = setTimeout(() => {
        if (this.isAILoading) {
          console.error('提示词处理超时');
          this.handleProcessingTimeout();
        }
      }, this.maxTranslationTime);
      
      // 调用AI进行提示词处理
      if (this.$refs.aiChat) {
        // 构建系统提示
        const systemPrompt = `你是一个专业的图像生成提示词优化专家。你的任务是将用户的中文提示词转化为高质量的英文提示词，以便于AI图像生成使用。
请分析用户提供的描述，提取关键元素，并将其转化为详细、精确且富有描述性的英文提示词。
回复时只需提供优化后的英文提示词，不需要任何解释或额外的文字。`;

        // 创建包含系统提示的消息历史
        const messages = [
          { role: 'system', content: systemPrompt }
        ];
        
        this.$refs.aiChat.sendMessage(this.prompt, messages);
      } else {
        // 如果AI组件不可用，直接使用原始提示词
        this.handleProcessingError(new Error('AI组件未就绪'));
      }
    },
    
    // 处理超时
    handleProcessingTimeout() {
      // 清除超时计时器
      if (this.translationTimeout) {
        clearTimeout(this.translationTimeout);
        this.translationTimeout = null;
      }
      
      // 隐藏加载提示
      uni.hideLoading();
      
      // 更新状态
      this.isAILoading = false;
      
      // 显示超时提示
      uni.showToast({
        title: '处理超时，使用原始提示词',
        icon: 'none',
        duration: 2000
      });
      
      // 使用原始内容
      this.prompt = this.originalPrompt;
      
      // 尝试重置AI组件
      if (this.$refs.aiChat && typeof this.$refs.aiChat.reset === 'function') {
        this.$refs.aiChat.reset();
      }
    },
    
    // 处理AI消息
    handleAIMessage(message) {
      // 对于流式返回，直接更新处理结果
      if (message && message.content) {
        this.processedPrompt += message.content;
        
        // 首次收到消息时显示处理区域
        if (!this.showTranslation && this.processedPrompt.trim() !== '') {
          this.showTranslation = true;
          uni.hideLoading();
        }
      }
    },
    
    // 处理AI消息更新完成
    handleMessagesUpdated(messages) {
      if (messages && messages.length > 0) {
        const lastMessage = messages[messages.length - 1];
        if (lastMessage.role === 'assistant' && lastMessage.content) {
          // 清除超时计时器
          if (this.translationTimeout) {
            clearTimeout(this.translationTimeout);
            this.translationTimeout = null;
          }
          
          // 确保处理结果完整
          this.processedPrompt = lastMessage.content.trim();
          
          // 显示处理区域
          this.showTranslation = true;
          
          // 隐藏加载提示
          uni.hideLoading();
          
          // 更新状态
          this.isAILoading = false;
        }
      }
    },
    
    // 处理AI加载状态
    handleAILoading(loading) {
      this.isAILoading = loading;
      
      // 加载结束时清除超时计时器
      if (!loading && this.translationTimeout) {
        clearTimeout(this.translationTimeout);
        this.translationTimeout = null;
        
        // 隐藏加载提示
        uni.hideLoading();
      }
    },
    
    // 处理AI错误
    handleAIError(error) {
      console.log('AI错误:', error);
      
      // 如果是SSE连接正常关闭，且有处理内容，则视为处理完成
      if (error && error.type === 'SSE_CLOSED' && this.processedPrompt.trim() !== '') {
        console.log('SSE连接正常关闭，处理完成');
        
        // 清除超时计时器
        if (this.translationTimeout) {
          clearTimeout(this.translationTimeout);
          this.translationTimeout = null;
        }
        
        // 更新状态
        this.isAILoading = false;
        
        // 隐藏加载提示
        uni.hideLoading();
        
        // 显示处理区域
        this.showTranslation = true;
        
        return;
      }
      
      // 其他错误情况，调用错误处理逻辑
      this.handleProcessingError(error);
    },
    
    // 处理提示词处理错误
    handleProcessingError(error) {
      console.error('提示词处理错误:', error);
      
      // 清除超时计时器
      if (this.translationTimeout) {
        clearTimeout(this.translationTimeout);
        this.translationTimeout = null;
      }
      
      // 更新状态
      this.isAILoading = false;
      
      // 隐藏加载提示
      uni.hideLoading();
      
      // 如果已有处理内容，则不显示错误提示，直接使用现有内容
      if (this.processedPrompt.trim() !== '') {
        console.log('虽有错误但已有处理内容，继续使用');
        this.showTranslation = true;
        return;
      }
      
      // 没有处理内容才显示错误提示
      uni.showToast({
        title: '处理失败，使用原始提示词',
        icon: 'none',
        duration: 2000
      });
    },
    
    // 使用处理后的提示词
    useProcessedPrompt() {
      // 阻止超时处理
      if (this.translationTimeout) {
        clearTimeout(this.translationTimeout);
        this.translationTimeout = null;
      }
      
      this.prompt = this.processedPrompt;
      this.showTranslation = false;
      
      // 处理完成后自动生成图像
      this.generateImages();
    },
    
    // 取消处理，使用原始提示词
    cancelProcessing() {
      // 阻止超时处理
      if (this.translationTimeout) {
        clearTimeout(this.translationTimeout);
        this.translationTimeout = null;
      }
      
      this.prompt = this.originalPrompt;
      this.showTranslation = false;
    },
    
    async generateImages() {
      if (!this.prompt.trim()) {
        uni.showToast({
          title: '请输入提示词',
          icon: 'none'
        });
        return;
      }
      
      this.isGenerating = true;
      this.generatedCount = 0;
      this.generatedImages = [];
      
      const selectedSize = this.imageSizes[this.sizeIndex];
      const selectedModel = this.availableModels[this.modelIndex];
      
      try {
        // 创建多个图像生成任务
        for (let i = 0; i < this.imageCount; i++) {
          const seed = Math.floor(Math.random() * 1000000);
          
          try {
            // 串行处理每个图像请求
            const imageUrl = await this.generateSingleImage(selectedModel, selectedSize, seed);
            
            if (imageUrl) {
              this.generatedImages.push({
                url: imageUrl,
                seed: seed
              });
              
              // 设置第一张图片为背景
              if (i === 0) {
                this.generatedImage = imageUrl;
              }
            }
          } catch (error) {
            console.error(`生成第${i+1}张图片失败:`, error);
          }
        }
        
        if (this.generatedImages.length > 0) {
          uni.showToast({
            title: `成功生成${this.generatedImages.length}张图像`,
            icon: 'success'
          });
        } else {
          uni.showToast({
            title: '生成图像失败，请重试',
            icon: 'none'
          });
        }
      } catch (error) {
        console.error('生成图像失败:', error);
        uni.showToast({
          title: '生成图像失败，请重试',
          icon: 'none'
        });
      } finally {
        this.isGenerating = false;
      }
    },
    
    async generateSingleImage(model, size, seed) {
      try {
        // 使用im2.js中的generateImageUrl方法
        const result = await generateImageUrl(this.prompt, {
          model: model,
          width: size.width,
          height: size.height,
          seed: seed
        });
        
        this.generatedCount++;
        
        // 返回生成的图像URL
        return result.imageUrl;
      } catch (error) {
        console.error('单张图像生成失败:', error);
        throw error;
      }
    },
    
    previewImage(index) {
      const urls = this.generatedImages.map(img => img.url);
      uni.previewImage({
        current: index,
        urls: urls
      });
    },
    
    clearImages() {
      // 删除临时文件
      this.generatedImages.forEach(image => {
        try {
          uni.getFileSystemManager().unlink({
            filePath: image.url,
            fail: () => {}
          });
        } catch (e) {}
      });
      
      this.generatedImages = [];
      this.generatedImage = null;
    }
  }
}
</script>

<style>
.container {
  position: relative;
  width: 100%;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-color: #121214;
  color: #ffffff;
}

.background-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
}

.background-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.background-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.4);
}

.content {
  z-index: 10;
  padding: 30px;
  border-radius: 16px;
  background-color: rgba(44, 44, 46, 0.6);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 80%;
  max-width: 500px;
}

.title {
  font-size: 24px;
  font-weight: bold;
  margin-bottom: 20px;
}

.form-item {
  width: 100%;
  margin-bottom: 16px;
}

.label {
  font-size: 16px;
  margin-bottom: 8px;
  display: block;
}

.input {
  width: 100%;
  height: 40px;
  background-color: rgba(255, 255, 255, 0.1);
  border-radius: 8px;
  padding: 0 12px;
  color: #ffffff;
}

.picker {
  width: 100%;
  height: 40px;
  background-color: rgba(255, 255, 255, 0.1);
  border-radius: 8px;
}

.picker-text {
  height: 40px;
  line-height: 40px;
  padding: 0 12px;
  color: #ffffff;
}

/* 翻译结果显示区域 */
.translate-container {
  margin-bottom: 20px;
  padding: 15px;
  background-color: rgba(255, 255, 255, 0.05);
  border-radius: 10px;
  border-left: 4px solid #d4a520;
  width: 100%;
}

.translate-content {
  display: flex;
  flex-direction: column;
  margin-bottom: 15px;
}

.original-text, .translated-text {
  font-size: 14px;
  line-height: 1.5;
  margin-bottom: 10px;
}

.original-text {
  color: rgba(255, 255, 255, 0.7);
}

.translated-text {
  color: #d4a520;
  font-weight: bold;
}

.translated-text-container {
  display: flex;
  align-items: center;
}

.typing-indicator {
  display: flex;
  align-items: center;
  margin-left: 10px;
}

.typing-indicator .dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: #d4a520;
  margin: 0 2px;
  animation: dot-flashing 1s infinite linear alternate;
}

.typing-indicator .dot:nth-child(2) {
  animation-delay: 0.2s;
}

.typing-indicator .dot:nth-child(3) {
  animation-delay: 0.4s;
}

.translate-actions {
  display: flex;
  justify-content: flex-end;
}

.translate-action {
  padding: 8px 15px;
  border-radius: 15px;
  font-size: 14px;
  margin-left: 10px;
}

.translate-action:first-child {
  background-color: #d4a520;
  color: #000000;
}

.translate-action:last-child {
  background-color: rgba(255, 255, 255, 0.1);
  color: #ffffff;
}

.button-group {
  display: flex;
  gap: 10px;
  margin-top: 20px;
  width: 100%;
}

.process-btn {
  flex: 1;
  background-color: rgba(212, 165, 32, 0.6);
  color: #ffffff;
  padding: 10px 20px;
  border-radius: 8px;
}

.generate-btn {
  flex: 2;
  background-color: #d4a520;
  color: #000000;
  padding: 10px 20px;
  border-radius: 8px;
  font-weight: bold;
}

.clear-btn {
  flex: 1;
  background-color: rgba(255, 255, 255, 0.2);
  color: #ffffff;
  padding: 10px 20px;
  border-radius: 8px;
}

.loading-container {
  margin-top: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid rgba(255, 255, 255, 0.3);
  border-radius: 50%;
  border-top-color: #d4a520;
  animation: spin 1s infinite linear;
}

.loading-text {
  margin-top: 10px;
  font-size: 14px;
  color: #d4a520;
}

.image-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  width: 100%;
  margin-top: 20px;
}

.image-item {
  position: relative;
  width: 48%;
  margin-bottom: 15px;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

.generated-image {
  width: 100%;
  height: 200px;
  object-fit: cover;
}

.image-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  padding: 8px;
  background: rgba(0, 0, 0, 0.5);
}

.image-seed {
  font-size: 12px;
  color: #ffffff;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

@keyframes dot-flashing {
  0% {
    opacity: 0.2;
  }
  100% {
    opacity: 1;
  }
}
</style> 